package com.ymm.platform.core.facade;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ymm.driver.api.constants.Entity.DriverEntity;
import com.ymm.lulutong.dto.OrderShipperDTO;
import com.ymm.platform.api.constants.dto.request.ComplaintsInfoRequest;
import com.ymm.platform.api.constants.dto.response.ComplaintsInfoResponse;
import com.ymm.platform.api.constants.dto.response.ComplaintsStateResponse;
import com.ymm.platform.api.constants.dto.response.PendingComplaintsInfoResponse;
import com.ymm.platform.api.facade.ComplaintsService;
import com.ymm.platform.api.utils.*;
import com.ymm.platform.dao.entity.Complaints;
import com.ymm.platform.dao.mapper.ComplaintsMapper;
import com.ymm.platform.dao.mq.sender.DriverComplaintsCompleteMsgSender;
import com.ymm.platform.dao.mq.sender.ShipperComplaintsCompleteMsgSender;
import com.ymm.platform.dao.rpc.DriverRPC;
import com.ymm.platform.dao.rpc.ShipperRPC;
import com.ymm.platform.dao.rpc.SystemRPC;
import com.ymm.system.api.dto.OrderAndCargoInfoResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: TODO
 * @Author: Xuecheng Li
 * @CreateTime: 2022-08-12  22:25
 * @Version: 1.0.0
 */
@Service
@Component
@Slf4j
public class ComplaintsServiceImpl implements ComplaintsService {

    /**
     * complaints DAO
     */
    @Resource
    ComplaintsMapper complaintsMapper;

    /**
     * 司机rpc服务
     */
    @Resource
    DriverRPC driverRPC;

    /**
     * 货主rpc服务
     */
    @Resource
    ShipperRPC shipperRPC;

    /**
     * 系统端rpc服务
     */
    @Resource
    SystemRPC systemRPC;

    @Resource
    private ShipperComplaintsCompleteMsgSender shipperComplaintsCompleteMsgSender;

    @Resource
    private DriverComplaintsCompleteMsgSender driverComplaintsCompleteMsgSender;

    /**
     * 查询指定申诉的申诉简略信息
     *
     * @param complaintsId
     * @Param: [complaintsId]
     * @return: com.ymm.platform.api.utils.Result<com.ymm.platform.api.constants.dto.response.ComplaintsInfoResponse>
     */
    @Override
    public Result<ComplaintsInfoResponse> queryComplaintsInfoByComplaintsId(Long complaintsId) {
        if (complaintsId == null) {
            return Result.fail(ResultCodeEnum.PARAM_NULL_ERROR);
        }

        Complaints complaints = complaintsMapper.selectComplaintsByComplaintsId(complaintsId);

        if (complaints == null) {
            return Result.fail(ResultCodeEnum.NO_SUCH_DATA);
        }

        ComplaintsInfoResponse complaintsInfoResponse = new ComplaintsInfoResponse();
        BeanUtils.copyProperties(complaints, complaintsInfoResponse);

        return Result.success(complaintsInfoResponse);
    }

    /**
     * 用户提交申诉请求
     *
     * @param complaintsInfo
     * @Param: complaintsInfo
     * @return: Result
     */
    @Override
    public Result commitComplaints(ComplaintsInfoRequest complaintsInfo) {

        //1.参数空值校验(防腐层校验) 必要性需要考虑 todo
        if (complaintsInfo == null ||
                complaintsInfo.getComplainantType() == null ||
                complaintsInfo.getComplainantId() == null ||
                complaintsInfo.getRespondentType() == null ||
                complaintsInfo.getComplaintsOrderId() == null ||
                complaintsInfo.getComplaintsDsc() == null) {
            return Result.fail(ResultCodeEnum.PARAM_NULL_ERROR);
        }

        //2.转化
        Complaints complaints = new Complaints();
        BeanUtils.copyProperties(complaintsInfo, complaints);

        //3.添加业务字段
        complaints.setComplaintsState(0);
        complaints.setCreatedTime(new Date());
        complaints.setUpdateTime(new Date());
        complaints.setIsDeleted(0);

        //4.保证接口幂等性(先查是否存在)

        Integer insertResult = complaintsMapper.insertComplaints(complaints);

        return Result.success();
    }

    /**
     * 用户查看历史申诉包含处理结果
     *
     * @param complainantId
     * @Param: [userId]
     * @return: Result<List < ComplaintsInfoResponse>>
     */
    @Override
    public Result<List<ComplaintsInfoResponse>> queryComplaintsInfo(Long complainantId) {

        //1.校验入参
        if (complainantId == null) {
            return Result.fail(null, ResultCodeEnum.PARAM_FORMAT_ERROR);
        }

        //2.数据库查询
        List<Complaints> complaintsResponses = complaintsMapper.selectComplaintsByComplainantId(complainantId);

        //3.数据转换
        if (complaintsResponses == null) {
            return Result.fail(null, ResultCodeEnum.NO_SUCH_DATA);
        }

        List<ComplaintsInfoResponse> complaintsInfoList = new ArrayList<>();
        for (Complaints complaints: complaintsResponses) {
            ComplaintsInfoResponse complaintsInfo = new ComplaintsInfoResponse();
            BeanUtils.copyProperties(complaints, complaintsInfo);
            complaintsInfoList.add(complaintsInfo);
        }

        return Result.success(complaintsInfoList);
    }

    /**
     * 用户根据订单id查询申诉状态
     *
     * @param orderId
     * @Param: [orderId]
     * @return: com.ymm.platform.api.utils.Result<java.lang.Integer>
     */
    @Override
    public Result<ComplaintsStateResponse> queryComplaintsStateByOrderId(Long orderId) {

        //1.校验参数(防腐层业务校验)
//        if (orderId == null) {
//            return Result.fail(ResultCodeEnum.PARAM_ERROR);
//        }

        //2.数据库查询
        Complaints complaints = complaintsMapper.selectComplaintsStateByOrderId(orderId);

        //3.数据转换
         if (complaints == null) {
                    return Result.fail(ResultCodeEnum.NO_SUCH_DATA);
         }
        ComplaintsStateResponse complaintsStateResponse = new ComplaintsStateResponse();
        BeanUtils.copyProperties(complaints, complaintsStateResponse);

        return Result.success(complaintsStateResponse);
    }

    /**
     * 用户取消指定申诉
     *
     * @param complaintsId
     * @Param: [userId, complaintsId]
     * @return: Result
     */
    @Override
    public Result cancelComplaints(Long complaintsId) {

        //1.入参校验
        if (complaintsId == null) {
            return Result.fail(null, ResultCodeEnum.IN_PARAM_ERROR);
        }

        //2.更新申诉单状态前先查询状态是否为进行中，如果是已完成或者已取消则更新失败
        Integer complaintsState = complaintsMapper.selectComplaintsStateByComplainantId(complaintsId);
//        Integer complaintsState = complaints.getComplaintsState();
        if (!complaintsState.equals(ComplaintsStateEnum.HANDLING.getCode())) {
            return Result.fail(null, ResultCodeEnum.CANCEL_PERMISSION_DENIED);
        }

        Integer isSuccess = complaintsMapper.updateComplaintsState(complaintsId, ComplaintsStateEnum.CANCELED.getCode(), new Date());
        log.info("取消是否成功，{}，1表示成功，0表示失败", isSuccess);
        return Result.success();
    }

    /**
     * 平台查询所有的待处理申诉详情（分页）
     * rpc多表联查
     * @Param: []
     * @return: Result<List<PendingComplaintsInfoResponse>>
     */
    @Override
    public Result<PageInfo<PendingComplaintsInfoResponse>> queryPendingComplaints(Integer pageNum, Integer pageSize) {

        log.info("queryPendingComplaints服务请求：pageNum:{}, pageSize:{}", pageNum, pageSize);

        // 1.查询所有待处理申诉（分页）
        PageHelper.startPage(pageNum, pageSize);
        List<Complaints> complaintsList = complaintsMapper.selectComplaintsByComplaintsState(ComplaintsStateEnum.HANDLING.getCode());
        PageInfo<Complaints> pageInfo = new PageInfo<>(complaintsList);

        complaintsList = pageInfo.getList();

        if (complaintsList == null) {
            return Result.fail(null, ResultCodeEnum.NO_SUCH_DATA);
        }

        //2.处理申诉单信息(姓名)
        List<PendingComplaintsInfoResponse> pendingComplaintsInfoResponses =
                new ArrayList<>(complaintsList.size());

        for (int i = 0; i < complaintsList.size(); i++) {

            Complaints complaints = complaintsList.get(i);
            PendingComplaintsInfoResponse pendingComplaintsInfo = new PendingComplaintsInfoResponse();

            //2.1 提取申诉人信息
            Long complainantId = complaints.getComplainantId();
            log.info("申诉人id：{}", complainantId);
            if (complaints.getComplainantType().equals(ComplainantTypeEnum.DRIVER.getCode())) {
                //2.1.1 查司机表详情
                DriverEntity driverEntity = driverRPC.getDriverInfoById(complainantId);
                //注入司机姓名信息 todo 其他信息待确定
                pendingComplaintsInfo.setComplainantName(driverEntity.getDriverName());
            } else {
                //2.1.2 查询货主表详情
                OrderShipperDTO orderShipperDTO = shipperRPC.getShipperInfo(complainantId);
                //注入货主姓名信息 todo 其他信息待确定
                pendingComplaintsInfo.setComplainantName(orderShipperDTO.getNickname());
            }

            //2.2 提取订单信息和货源信息
            Long orderId = complaints.getComplaintsOrderId();
            OrderAndCargoInfoResponse orderAndCargoInfo = systemRPC.getOrderAndCargoInfo(orderId);
            BeanUtils.copyProperties(orderAndCargoInfo, pendingComplaintsInfo);

            //2.3 提取被申诉人信息
            if (complaints.getRespondentType().equals(RespondentTypeEnum.PLATFORM.getCode())) {
                pendingComplaintsInfo.setRespondentName(RespondentTypeEnum.PLATFORM.getMessage());
            }
            else if (complaints.getRespondentType().equals(RespondentTypeEnum.DRIVER.getCode())) {
                Long respondentId = orderAndCargoInfo.getDriverId();
                DriverEntity driverEntity = driverRPC.getDriverInfoById(respondentId);
                pendingComplaintsInfo.setRespondentName(driverEntity.getDriverName());
            } else {
                Long respondentId = orderAndCargoInfo.getShipperId();
                OrderShipperDTO orderShipperDTO = shipperRPC.getShipperInfo(respondentId);
                pendingComplaintsInfo.setRespondentName(orderShipperDTO.getNickname());
            }

            //2.4 提取申诉表信息
            BeanUtils.copyProperties(complaints, pendingComplaintsInfo);

            //2.5 放入待处理申诉list
            pendingComplaintsInfoResponses.add(pendingComplaintsInfo);
        }

        PageInfo<PendingComplaintsInfoResponse> resultPage = new PageInfo<>();
        resultPage.setList(pendingComplaintsInfoResponses);
        resultPage.setSize(pageInfo.getSize());
        resultPage.setTotal(pageInfo.getTotal());

        return Result.success(resultPage);
    }

    /**
     * 提交申诉处理结果
     *
     * @param complaintsId
     * @param handleDsc
     * @return: Result
     */
    @Override
    public Result commitComplaintsHandleComment(Long complaintsId, String handleDsc) throws MQBrokerException, RemotingException, InterruptedException, MQClientException {

        //1.参数校验
        if (complaintsId == null || handleDsc == null) {
            return Result.fail(ResultCodeEnum.PARAM_NULL_ERROR);
        }

        //2.更新处理结果和处理状态（sql中要求申诉状态必须为0）
        Integer isSuccess = complaintsMapper.updateComplaintsStateAndHandleDsc(complaintsId,
                handleDsc, ComplaintsStateEnum.FINISH.getCode(), new Date());

        if (isSuccess.equals(0)) {
            return Result.fail(null, ResultCodeEnum.HANDLE_PERMISSION_DENIED);
        }

        Complaints complaints = complaintsMapper.selectComplaintsByComplaintsId(complaintsId);

        if(complaints.getComplainantType().equals(ComplainantTypeEnum.SHIPPER.getCode())){
            shipperComplaintsCompleteMsgSender.send(complaintsId, complaints.getComplainantId(), complaints.getComplaintsOrderId(), 2, null);
        } else if (complaints.getComplainantType().equals(ComplainantTypeEnum.DRIVER.getCode())){
            driverComplaintsCompleteMsgSender.send(complaintsId, complaints.getComplainantId(), complaints.getComplaintsOrderId(), 2, null);
        }

        return Result.success();
    }
}
